<template>
  <scroll
    ref="suggest"
    class="suggest"
    :data="result"
    :bounceTop="false"
    pullup
    beforeScroll
    @scrollToEnd="searchMore"
    @beforeScroll="listScroll"
  >
    <ul class="suggest-list">
      <li @click="selectItem(item)" class="suggest-item" v-for="(item, index) in result" :key="index">
        <div class="icon">
          <i :class="getIconCls(item)"></i>
        </div>
        <div class="name">
          <p class="text" v-html="getDisplayName(item)" :class="{ no: !item.canplay && item.type !== 'singer' }"></p>
        </div>
      </li>
      <loading v-show="hasMore" title=""></loading>
    </ul>
    <div v-show="!hasMore && !result.length" class="no-result-wrapper">
      <no-result title="抱歉，暂无搜索结果"></no-result>
    </div>
  </scroll>
</template>

<script>
import Scroll from 'components/scroll/scroll';
import Loading from 'components/loading/loading';
import NoResult from 'components/no-result/no-result';
import { search } from 'api/search';
import { createSong, songAddUrl } from 'common/js/song';
import { mapMutations, mapActions } from 'vuex';
import { getSongUrl, getSongDetail } from 'api/song';

const TYPE_SINGER = 'singer';
const pagesize = 20;

export default {
  components: { Scroll, Loading, NoResult },
  props: {
    showSinger: {
      type: Boolean,
      default: false,
    },
    query: {
      type: String,
      default: '',
    },
  },
  data() {
    return {
      page: 1,
      hasMore: true,
      singers: [],
      songs: [],
      songids: [],
      bugSongs: [],
    };
  },
  watch: {
    query(newQuery) {
      if (newQuery) {
        this.search(newQuery);
      } else {
        this.songs = [];
        this.singers = [];
      }
    },
  },
  computed: {
    result() {
      return this.singers.concat(this.songs);
    },
  },
  methods: {
    refresh() {
      this.$refs.suggest.refresh();
    },
    async search() {
      this.page = 1;
      this.hasMore = true;
      this.songs = [];
      // 第一次搜索将列表滚动到顶部
      this.$refs.suggest.scrollTo(0, 0);
      // 搜索歌手
      if (this.showSinger) {
        search(this.query, 5, 1, true).then((res) => {
          this.singers = this._normalizeSingers(res.result);
        });
      }
      // 搜索歌曲
      await search(this.query, pagesize, this.page, false).then((res) => {
        this.songids = res.result.songs.map((item) => item.id);
        this._checkMore(res.result);
      });
      // 拿 ids多请求一次
      await getSongDetail(this.songids.join(',')).then((res) => {
        this.bugSongs = this._normalizeSongs(res.songs);
      });
      // 添加播放地址
      await getSongUrl(this.songids.join(',')).then((res) => {
        this._songAddUrl(res.data);
      });
    },
    async searchMore() {
      if (!this.hasMore) {
        return;
      }
      this.page++;
      await search(this.query, pagesize, this.page, false).then((res) => {
        this.songids = res.result.songs.map((item) => item.id);
        this._checkMore(res.result);
      });
      // 拿 ids多请求一次
      await getSongDetail(this.songids.join(',')).then((res) => {
        this.bugSongs = this._normalizeSongs(res.songs);
      });
      // 添加播放地址
      await getSongUrl(this.songids.join(',')).then((res) => {
        this._songAddUrl(res.data);
      });
    },
    listScroll() {
      this.$emit('listScroll');
    },
    selectItem(item) {
      if (item.type === TYPE_SINGER) {
        const singer = { id: item.id, name: item.name, avatar: item.img1v1Url };
        this.setSinger(singer);
        this.$router.push({
          path: `/search/${singer.id}`,
        });
      } else {
        if (item.canplay) {
          this.insertSong(item);
        } else {
          this.showToast(item.reason);
        }
      }
      this.$emit('select', item.name);
    },
    getDisplayName(item) {
      if (item.type === TYPE_SINGER) {
        return item.name;
      } else {
        return `${item.name}-${item.singer}`;
      }
    },
    getIconCls(item) {
      if (item.type === TYPE_SINGER) {
        return 'icon-mine';
      } else {
        return 'icon-music';
      }
    },
    _normalizeSingers(data) {
      let ret = [];
      if (data.artists && data.artists) {
        data.artists.forEach((item) => {
          ret.push({ ...item, ...{ type: TYPE_SINGER } });
        });
      }
      return ret;
    },
    _normalizeSongs(songs) {
      let res = [];
      songs.forEach((item) => {
        if (item.id && item.al && item.al.id) {
          res.push(createSong(item));
        }
      });
      return res;
    },
    _songAddUrl(urls) {
      this.songs = this.songs.concat(
        this.bugSongs.map((song) => {
          songAddUrl(song, urls);
          return song;
        })
      );
    },
    _checkMore(res) {
      const maxL = res.songCount;
      const nowL = this.page * pagesize;
      if (nowL >= maxL) {
        this.hasMore = false;
      }
    },
    ...mapMutations(['setSinger']),
    ...mapActions(['insertSong', 'showToast']),
  },
};
</script>

<style scoped lang="stylus" rel="stylesheet/stylus">
@import "~common/stylus/variable"
@import "~common/stylus/mixin"

.suggest
  height: 100%
  overflow: hidden
  .suggest-list
    padding: 0 30px
    .suggest-item
      display: flex
      align-items: center
      padding-bottom: 20px
    .icon
      flex: 0 0 30px
      width: 30px
      [class^="icon-"]
        font-size: 14px
        color: $color-text-d
    .name
      flex: 1
      font-size: $font-size-medium
      color: $color-text-d
      overflow: hidden
      .text
        no-wrap()
        &.no
          color: rgba(255, 255, 255, 0.1);
  .no-result-wrapper
    position: absolute
    width: 100%
    top: 50%
    transform: translateY(-50%)
</style>
